Architectural Principles
Separation of concerns
- Domain owns business truth:
- entities
- value objects
- invariants
- domain events
- Application owns orchestration:
- commands
- queries
- typed handlers
- event-driven use cases
- Infrastructure owns integration mechanics:
- DataHub transport contracts
- schemas
- serialization
- authentication
- clients
- endpoint routing
- integration-specific handlers and factories
- diagnostics
Clean boundaries
- DataHub-specific details remain in
DMC.Infrastructure\Integrations\DataHub - generated DataHub transport classes are internal
- generated transport classes do not enter Domain
- business logic is not implemented in Infrastructure
- Application is the boundary between integration mechanics and business behavior
BRS-oriented design
The primary unit of organization is the DataHub integration point, grouped by BRS and message family.
Each BRS owns:
- its contract definitions
- its integration-specific mapping
- its inbound handlers
- its outbound builders/publishers
This keeps each integration point self-contained and reviewable.
BRS-oriented design
The primary unit of organization is the DataHub integration point, grouped by BRS and message family.
Each BRS owns:
- its contract definitions
- its integration-specific mapping
- its inbound handlers
- its outbound builders/publishers
This keeps each integration point self-contained and reviewable.
Layer responsibilities
| Layer | Responsibility |
|---|---|
DMC.Domain | Business model, invariants, domain events |
DMC.Application | Use-case orchestration, commands, queries, handlers |
DMC.Infrastructure\Integrations\DataHub | DataHub contracts, schema ownership, serialization, auth, transport, mapping, routing, diagnostics |
Dependency direction
API -> Application -> Domain
Infrastructure -> Application
Domain -> no dependency on DataHub transport contracts
Rules:
- There is no
DMC.Application.DataHubarea - There are no generated DataHub DTOs in Domain
- Infrastructure does not own business invariants
- New DataHub reads are not modeled as repository query helpers
- New business flows are exposed through Application commands, queries, and handlers
DataHub Contract Model
Contract source
The source of truth for DataHub transport contracts is the official JSON Schema set stored under:
DMC.Infrastructure\Integrations\DataHub\Schemas
Generated classes
Generated classes are:
- produced from the official schemas
- transport-only
- internal
- owned by Infrastructure
- tied to a specific DataHub message family
Generated classes represent the wire contract only. They do not represent business concepts.
Generation goal
The target output is simple transport classes:
- POCO-style classes
System.Text.Jsonserialization attributes- minimal runtime complexity
- no schema-fidelity-heavy runtime model unless explicitly required
Mapping Boundaries
There are four distinct model layers in the integration:
| Layer | Role |
|---|---|
| Generated DataHub contracts | Exact transport shape |
| Infrastructure mapping/factories/handlers | Protocol-specific transformation |
| Application commands/queries | Business orchestration boundary |
| Domain entities/value objects | Business truth |
Mapping rules
- Generated DataHub contracts do not enter Domain
- Inbound transport documents are mapped in Infrastructure into application commands/queries
- Outbound DataHub documents are built in Infrastructure from business data prepared by Application
- Domain remains unaware of DataHub transport structures
- Mapping helpers are introduced only where they improve clarity or reuse
Integration Runtime Model
Outbound model
Outbound DataHub messages are initiated by Application and constructed in Infrastructure.
Target flow:
Domain event or application use case
-> application handler gathers required business data
-> infrastructure builds DataHub document
-> infrastructure serializes and sends the document
-> infrastructure handles technical response, diagnostics, and retry behavior
Responsibilities:
- Application
- decides that a DataHub interaction is required
- gathers business data
- defines transaction boundaries
- Infrastructure
- builds the DataHub contract
- applies protocol defaults
- serializes JSON
- calls the configured endpoint
- handles transport-level failures
Inbound model
Inbound DataHub messages are received and interpreted in Infrastructure, then translated into business operations.
Target flow:
DataHub message received
-> infrastructure selects message family
-> infrastructure deserializes to generated contract
-> integration-local handler processes document
-> integration-local handler maps to application command/query
-> application executes business behavior
Responsibilities:
- Infrastructure
- fetches or receives the message
- identifies the RSM/BRS
- deserializes the transport document
- performs protocol-level validation
- maps to application request
- Application
- performs business handling
- persists business changes
- raises follow-up domain events if needed
Integration-local handlers
Integration-local inbound handlers use an Infrastructure-local abstraction such as:
IRsmMessageHandler<TMessage>
These handlers are responsible for protocol-specific handling only. They do not contain business invariants.